﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;


namespace mc_tester
{
    public class Communication
    {
        bool logsor=false;
        int _buffer=100;
        List<byte> lb = new List<byte>();
        //a serial portunk
        private SerialPort _serialPort;

        //az MC eszközünk
        private Device _device;

        //konstruktor
        public Communication(Device d, string pn, string br, string db, string sb, string pa)
        {
            _device = d;

            //soros port létrehozás
            _serialPort = new SerialPort();

            //ezt csak MC módban használjuk, PC módban egybő várjuk a választ a serialon keresztül
            _serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

            //serial port beállítások
            _serialPort.PortName = pn;
            _serialPort.BaudRate = Convert.ToInt32(br);
            _serialPort.DataBits = Convert.ToInt32(db);

            //ennyi időt várunk a parancs ACK-ra
            _serialPort.ReadTimeout = Properties.Settings.Default.SERIALREADTIMEOUT;

            //stop Combo
            switch (sb){
                case "None":
                    _serialPort.StopBits = System.IO.Ports.StopBits.None;
                    break;
                case "One":
                    _serialPort.StopBits = System.IO.Ports.StopBits.One;
                    break;
                case "OnePointFive":
                    _serialPort.StopBits=System.IO.Ports.StopBits.OnePointFive;
                    break;
                case "Two":
                    _serialPort.StopBits=System.IO.Ports.StopBits.Two;
                    break;
                default:
                    _serialPort.StopBits=System.IO.Ports.StopBits.None;
                    break;
            }

            //Parity kombo
            switch (pa)
            {
                case "None":
                    _serialPort.Parity = Parity.None;
                    break;
                case "Even":
                    _serialPort.Parity = Parity.Even;
                    break;
                case "Mark":
                    _serialPort.Parity = Parity.Mark;
                    break;
                case "Odd":
                    _serialPort.Parity = Parity.Odd;
                    break;
                case "Space":
                    _serialPort.Parity = Parity.Space;
                    break;
                default:
                    _serialPort.Parity = Parity.None;
                    break;
            }
        }

        //szükségünk van a serial portra
        public SerialPort serialPort
        {
            get
            {
                return _serialPort;
            }
            set
            {
                _serialPort = value;
            }
        }

        //itt figyeljük, mi jött be soros porton és feldolgozzuk
        private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            
            byte[] data = new byte[serialPort.BytesToRead];
            serialPort.Read(data, 0, data.Length);


            for (int i = 0; i < data.Length; i++)
            {
                lb.Add(data[i]);
                Console.Write(Convert.ToInt32(data[i]).ToString("X2")+" ");
                if (data[i]==0x7e && logsor){
                    //Console.WriteLine("");
                    MCPacket mcpacket=new MCPacket(lb);
                    lb.Clear();
                }
                if (data[i] == 0x7e)
                {
                    logsor = !logsor;
                }
                
            }
            //Console.WriteLine("");
        }

        //keresük byte alapján a portot
        Port byte2Port(byte b)
        {
            Port ret = null;

            foreach (KeyValuePair<string, Port> pair in _device._ports)
            {
                if (b == pair.Value.byteValue)
                    ret = pair.Value;
            }

            return ret;
        }

        //üzenet feldolgozás
        private void messageprocess(){

            return;

            byte[] b = new byte[_buffer];

            //buffer nullázás
            for (int i = 0; i < _buffer; i++)
            {
                b[i] = 0;
            }

            //olvasunk, ha van honnan, és akkor is csak adott ideig
            try
            {
                _serialPort.Read(b, 0, _buffer);
            }
            catch (TimeoutException)
            {
                Console.WriteLine("Nem jött időben válasz...");
                return;
            }
            catch (Exception)
            {
                Console.WriteLine("Hiba a serial porton...");
                return;
            }    
            
        }

        //bájtokat küldünk a soros porton
        public void sendBytes(List<byte> command)
        {
            byte[] b = new byte[command.Count];
            int i = 0;
            foreach (byte value in command)
            {
                b[i] = value;
                i++;
            }
            try
            {
                _serialPort.Write(b, 0, command.Count);

            }
            catch (Exception)
            {
                Console.WriteLine("Hiba a serial porton...");
                return;
            }

            //ha PC vagyok, egyből kérem is az esetleges ACK-t
            //if (!Properties.Settings.Default.MCMODE)
            //    messageprocess();
        }


    } //end Communication class
}
